﻿
#include "stream/H264Stream.h"
#include "nalu/SeqParamSet.h"

#include <iostream>
#include <qdebug.h>
#include <assert.h>
#include <vector>
#include <qdebug.h>




CH264StreamFile::CH264StreamFile(char *fileName)
    :m_inputFile(NULL)
    ,m_fileName(fileName)
{
    qDebug() << "File name :" << m_fileName.c_str();


    m_inputFile = fopen(m_fileName.c_str(), "r");
    assert(m_inputFile != NULL);

}
int CH264StreamFile::ParseH264Bitstream()
{

    int ret = 0;
    uint8_t nalType = 0;

    CSeqParamSet * sps = NULL;

    do
    {
        ret = find_nal_prefix();
        //解析NAL UNIT
        if (m_nalVec.size())
        {
            nalType = m_nalVec[0] & 0x1F;

            switch (nalType)
            {
                case NALU_TYPE_SPS:

                    sps = new CSeqParamSet(m_nalVec);
                    qDebug() <<"find a sps....";
                    delete sps;

                    break;
                case NALU_TYPE_PPS:

                    qDebug() <<"find a pps....";
                    break;

                default:
                    qDebug() << "nalType :" <<nalType;
                    break;
            }
        }

    } while (ret);


    return 0;
}

int CH264StreamFile::find_nal_prefix()
{
    uint8_t prefix[3] = { 0 };
    uint8_t fileByte;
    /*
    [0][1][2] = {0 0 0} -> [1][2][0] ={0 0 0} -> [2][0][1] = {0 0 0}
    getc() = 1 -> 0 0 0 1
    [0][1][2] = {0 0 1} -> [1][2][0] ={0 0 1} -> [2][0][1] = {0 0 1}
    */

    m_nalVec.clear();

    int pos = 0, getPrefix = 0;
    for (int idx = 0; idx < 3; idx++)
    {
        if(( prefix[idx] = getc(m_inputFile))!=EOF)
        {
            m_nalVec.push_back(prefix[idx]);
        }
        else
        {
            qDebug() <<"read no....";
            return 0;
        }
    }

    while (!feof(m_inputFile))
    {
        if ((prefix[pos % 3] == 0) && (prefix[(pos + 1) % 3] == 0) && (prefix[(pos + 2) % 3] == 1))
        {
            //0x 00 00 01 found
            getPrefix = 1;
            m_nalVec.pop_back();
            m_nalVec.pop_back();
            m_nalVec.pop_back();
            break;
        }
        else if ((prefix[pos % 3] == 0) && (prefix[(pos + 1) % 3] == 0) && (prefix[(pos + 2) % 3] == 0))
        {
            if (1 == getc(m_inputFile))
            {
                //0x 00 00 00 01 found
                getPrefix = 2;
                m_nalVec.pop_back();
                m_nalVec.pop_back();
                m_nalVec.pop_back();
                break;
            }
        }
        else
        {
            if((fileByte = getc(m_inputFile))!=EOF)
            {
                prefix[(pos++) % 3] = fileByte;
                m_nalVec.push_back(fileByte);
            }
            else
            {
                qDebug() <<"read no....";
                return 0;
            }
        }
    }

    return getPrefix;
}

void CH264StreamFile::ebsp_to_sodb()
{
    if (m_nalVec.size() < 3)
    {
        return;
    }

    for (std::vector<uint8_t>::iterator itor = m_nalVec.begin() + 2; itor != m_nalVec.end(); )
    {
        if ((3 == *itor) && (0 == *(itor-1)) && (0 == *(itor-2)))
        {
            itor = m_nalVec.erase(itor);
        }
        else
        {
            itor++;
        }
    }
}

CH264StreamFile::~CH264StreamFile()
{
    qDebug() <<__FUNCTION__;
    m_nalVec.clear();

    if(m_inputFile)
    {
        fclose(m_inputFile);
        m_inputFile = NULL;
    }

}
